package org.ragdollcat.first.manager.upload;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.CIObject;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.qcloud.cos.model.ciModel.persistence.ProcessResults;
import lombok.extern.slf4j.Slf4j;
import org.ragdollcat.first.config.CosClientConfig;
import org.ragdollcat.first.exception.BusinessException;
import org.ragdollcat.first.exception.ErrorCode;
import org.ragdollcat.first.manager.CosManager;
import org.ragdollcat.first.model.dto.picture.UploadPictureResult;
import org.ragdollcat.first.util.HexColorExpander;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;

/**
 * 文件上传抽象类
 */
@Slf4j
public abstract class AbsFileUpload {

    @Resource
    private CosManager cosManager;


    @Resource
    private CosClientConfig cosClientConfig;


    /**
     * 上传文件
     *
     * @param source       文件数据
     * @param uploadPrefix 前缀
     * @return
     */
    public UploadPictureResult uploadPicture(Object source, String uploadPrefix) {
        //校验参数
        this.vaildParams(source);

        //重构文件名 例：2025-08-17_ArDerNqpvVVEfVOj.jpg 为什么要重构文件名？为了防止文件名中有&=等特殊符号导致请求出现问题
        String fileName = this.overwriteFileName(source);

        //上传文件
        //前缀 拼接上文件名  /picture/xxxxx/2025-08-17_ArDerNqpvVVEfVOj.jpg
        String filePath = String.format("%s/%s", uploadPrefix, fileName);
        File file = null;
        try {
            file = File.createTempFile(filePath, null);
            processFile(source, file);
            PutObjectResult putObjectResult = cosManager.putPictureObject(filePath, file);
            //解析结果
            ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
            //得到处理结果
            ProcessResults processResults = putObjectResult.getCiUploadResult().getProcessResults();
            List<CIObject> objectList = processResults.getObjectList();
            if (CollUtil.isNotEmpty(objectList)) {
                //图片格式转换规则
                CIObject ciObject = objectList.get(0);
                String thumbnailUrl = null;
                if (objectList.size() > 1) {
                    //图片压缩规则
                    CIObject thumbnailCiObject = objectList.get(1);
                    //图片压缩规则不为空，才给thumbnailUrl赋值
                    thumbnailUrl = "https://" + thumbnailCiObject.getLocation();
                }
                Integer width = ciObject.getWidth();
                Integer height = ciObject.getHeight();
                return new UploadPictureResult(
                        "https://" + ciObject.getLocation(),
                        thumbnailUrl,
                        FileUtil.mainName(getOriginalFilename(source)),
                        ciObject.getSize().longValue(),
                        width,
                        height,
                        NumberUtil.round(width * 1.0 / height, 2).doubleValue(),
                        ciObject.getFormat(),
                        HexColorExpander.expandHexColor(imageInfo.getAve()));
            }
            int width = imageInfo.getWidth();
            int height = imageInfo.getHeight();
            return new UploadPictureResult(
                    "https://" + cosClientConfig.getHost() + filePath,
                    null,
                    FileUtil.mainName(getOriginalFilename(source)),
                    FileUtil.size(file),
                    width,
                    height,
                    NumberUtil.round(width * 1.0 / height, 2).doubleValue(),
                    imageInfo.getFormat(),
                    HexColorExpander.expandHexColor(imageInfo.getAve())
            );
        } catch (Exception e) {
            log.error("上传文件出现异常，路径：{}", filePath, e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "上传文件失败");
        } finally {
            this.clearTemporaryFile(file);
        }

    }

    /**
     * 处理文件来源
     *
     * @param source
     * @param file
     */
    protected abstract void processFile(Object source, File file);

    /**
     * 校验参数
     *
     * @param source
     */
    protected abstract void vaildParams(Object source);

    /**
     * 得到原始文件名
     *
     * @param source
     * @return
     */
    protected abstract String getOriginalFilename(Object source);

    private void clearTemporaryFile(File file) {
        if (ObjUtil.isNotEmpty(file)) {
            boolean delete = file.delete();
            if (!delete) {
                log.error("临时文件删除错误");
            }
        }
    }

    /**
     * 重构文件名：Snipaste_2025-08-17_17-56-45.png => 2025-08-17_ArDerNqpvVVEfVOj.png
     *
     * @param source
     * @return
     */
    private String overwriteFileName(Object source) {

        //1.生成16位数随机字符串
        //ArDerNqpvVVEfVOj
        String randomUUID = RandomUtil.randomString(16);
        //2.获取当前时间
        //2025-08-17
        String date = DateUtil.formatDate(new Date());
        //获取文件后缀
        //png
        String suffix = FileUtil.getSuffix(getOriginalFilename(source));
        return String.format("%s_%s.%s", date, randomUUID, suffix);
    }


}
